import 'dart:math';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

import '../base/theme.dart';
import '../util/physiological_cycle_count.dart';

///动态绘制环形图片
class CyclePainter extends CustomPainter {
  final List<CycleDay> days;

  final ui.Image? ovulationImage; // 新增：排卵期图片（预加载后传入）

  CyclePainter(this.days, {this.ovulationImage});

  @override
  void paint(Canvas canvas, Size size) {
    final rect = Rect.fromLTWH(0, 0, size.width, size.height);
    final center = rect.center;
    final radius = size.width / 2;
    const strokeWidth = 12.0;

    // 1. 按连续相同阶段和是否未来日期分组
    List<PhaseGroup> phaseGroups = [];
    if (days.isNotEmpty) {
      CycleDay firstDay = days[0];
      GroupKey currentKey = GroupKey(
        phase: firstDay.rawPhase,
        isFuture: firstDay.date.millisecondsSinceEpoch >
            DateTime.now().millisecondsSinceEpoch,
      );
      int currentCount = 1;
      int currentStartIndex = 0; // 新增：当前组起始日期索引

      // 遍历剩余日期进行分组
      for (int i = 1; i < days.length; i++) {
        CycleDay day = days[i];
        GroupKey newKey = GroupKey(
          phase: day.rawPhase,
          isFuture: day.date.millisecondsSinceEpoch >
              DateTime.now().millisecondsSinceEpoch,
        );

        if (newKey == currentKey) {
          currentCount++; // 同组则增加计数
        } else {
          // 新增：记录当前组的日期索引范围（startIndex ~ endIndex）
          phaseGroups.add(PhaseGroup(
            key: currentKey,
            duration: currentCount,
            startIndex: currentStartIndex,
            endIndex: currentStartIndex + currentCount - 1,
          ));
          currentKey = newKey;
          currentStartIndex += currentCount; // 更新下一组起始索引
          currentCount = 1;
        }
      }
      // 添加最后一组（新增日期索引范围）
      phaseGroups.add(PhaseGroup(
        key: currentKey,
        duration: currentCount,
        startIndex: currentStartIndex,
        endIndex: currentStartIndex + currentCount - 1,
      ));
    }

    // 2. 计算角度参数
    const phaseGap = pi / 30; // 组间间隙角度（5°，可调整）
    const endGap = pi / 13;
    final totalGroups = phaseGroups.length;
    final totalGapAngle = (totalGroups - 1) * phaseGap; // 总组间间隙角度
    final totalDays = days.length;
    // 总可用弧形角度 = 完整圆周 - 组间间隙 - 末端20度间隙
    final totalArcAngle = 2 * pi - totalGapAngle - endGap;
    final anglePerDay = totalArcAngle / totalDays; // 单日角度基数（按剩余角度分配）

    // 3. 绘制白色背景圆环（保持完整）
    final backgroundPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round
      ..color = Colors.white12;
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius - strokeWidth / 2),
      0,
      2 * pi,
      false,
      backgroundPaint,
    );

    // 4. 绘制各阶段组弧形及排卵期图片
    double currentStartAngle = -pi / 2.16; // 起始角度（顶部）
    final paint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round;

    bool hasNonFutureFertileGroup = phaseGroups.any((group) =>
            !group.key.isFuture && // 非未来组
            GroupKey._isFertileRelated(group.key.phase) // 易孕期相关阶段
        );

    for (final group in phaseGroups) {
      // 计算当前组的弧形角度
      final isFutureFertileGroup =
          group.key.isFuture && GroupKey._isFertileRelated(group.key.phase);

      //检查当前组是否包含排卵日（RawPhase.Ovulation）
      bool hasOvulationDay = false;
      if (group.duration > 0) {
        for (int i = group.startIndex; i <= group.endIndex; i++) {
          if (days[i].rawPhase == RawPhase.Ovulation) {
            hasOvulationDay = true;
            break; // 找到一个排卵日即可退出
          }
        }
      }

      final baseAngle = group.duration * anglePerDay;
      final adjustedAngle =
          hasOvulationDay ? baseAngle - (pi / 30) : baseAngle; // 10° = π/18弧度

      final groupAngle = hasNonFutureFertileGroup && isFutureFertileGroup
          ? 0.0
          : adjustedAngle; // 使用调整后的角度

      // 设置组颜色（未来日期为透明）
      paint.color = group.key.isFuture
          ? futurePhaseColor(group.key.phase)
          : phaseColor(group.key.isFuture, group.key.phase);

      // 绘制组弧形
      if (groupAngle > 0) {
        canvas.drawArc(
          Rect.fromCircle(center: center, radius: radius - strokeWidth / 2),
          currentStartAngle,
          groupAngle,
          false,
          paint,
        );
      }

      // 新增：检查当前组是否包含排卵期，并绘制图片
      if (group.duration > 0) {
        // 遍历组内日期，查找排卵期
        for (int i = group.startIndex; i <= group.endIndex; i++) {
          if (days[i].rawPhase == RawPhase.Ovulation) {
            // 计算排卵期所在天数在组内的偏移量
            final dayOffset = i - group.startIndex;
            // 计算排卵期弧形的中心角度
            final ovulationCenterAngle = currentStartAngle +
                (dayOffset + 0.5) * anglePerDay; // +0.5 取天弧形的中心
            // 计算图片绘制坐标（基于圆心和半径）
            final imageRadius = (radius - strokeWidth / 2);
            final imageX = center.dx + imageRadius * cos(ovulationCenterAngle);
            final imageY = center.dy + imageRadius * sin(ovulationCenterAngle);

            if (ovulationImage != null) {
              final sourceRect = Rect.fromLTWH(
                  0,
                  0,
                  ovulationImage!.width.toDouble(),
                  ovulationImage!.height.toDouble());

              // 保持宽高比缩放（目标宽度可调整，此处保持20.0）
              const targetWidth = 20.0;
              final scale = targetWidth / ovulationImage!.width;
              final targetHeight = ovulationImage!.height * scale;

              // 绘制图片（居中对齐，位于弧形上方）
              canvas.drawImageRect(
                ovulationImage!,
                sourceRect,
                Rect.fromCenter(
                  center: Offset(imageX, imageY), // 角度中心对齐，确保居中
                  width: targetWidth,
                  height: targetHeight,
                ),
                Paint(),
              );
            }
            break; // 找到一个排卵期即可退出循环
          }
        }
      }

      // 更新起始角度（加上当前组角度和间隙）
      currentStartAngle += groupAngle + phaseGap;
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

/// 阶段颜色
Color phaseColor(bool isFuture, RawPhase phase) {
  switch (phase) {
    case RawPhase.Menstruation:
      return const Color(ThemeUtil.primarPredictionValue);
    case RawPhase.Follicular:
      return const Color(ThemeUtil.primarFollicularValue);
    case RawPhase.FertilePre:
    case RawPhase.FertilePost:
    case RawPhase.Ovulation:
      return const Color(ThemeUtil.primarMainPregnancyValue);
    case RawPhase.Luteal:
      return const Color(ThemeUtil.primarLutealValue);
  }
}

/// 未来阶段颜色
Color futurePhaseColor(RawPhase phase) {
  if (phase == RawPhase.FertilePre ||
      phase == RawPhase.FertilePost ||
      phase == RawPhase.Ovulation) {
    return const Color(ThemeUtil.primarMainPredictionValue);
  }
  return Colors.transparent;
}

/// 辅助类：阶段组键（用于判断是否同组）
class GroupKey {
  final RawPhase phase;
  final bool isFuture;

  GroupKey({required this.phase, required this.isFuture});

  // 判断是否为易孕期相关阶段（FertilePre/FertilePost/Ovulation）
  static bool _isFertileRelated(RawPhase phase) {
    return phase == RawPhase.FertilePre ||
        phase == RawPhase.FertilePost ||
        phase == RawPhase.Ovulation;
  }

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is GroupKey &&
          runtimeType == other.runtimeType &&
          isFuture == other.isFuture &&
          (_isFertileRelated(phase) && _isFertileRelated(other.phase) ||
              phase == other.phase);

  @override
  int get hashCode =>
      Object.hash(_isFertileRelated(phase) ? 'fertile_group' : phase, isFuture);
}

/// 辅助类：阶段组信息
class PhaseGroup {
  final GroupKey key;
  final int duration; // 组内天数
  final int startIndex; // 起始日期索引（新增）
  final int endIndex; // 结束日期索引（新增）

  PhaseGroup({
    required this.key,
    required this.duration,
    required this.startIndex, // 新增参数
    required this.endIndex, // 新增参数
  });
}
